藉由 React.Suspense 延遲載入
再使用 primitive 簡化模型使用
function _GltfScene() {
const gltf = useLoader(GLTFLoader, 'https://modelviewer.dev/shared-assets/models/NeilArmstrong.glb')
return (
<Suspense fallback={null} scale={1}>
<primitive object={gltf.scene} />
</Suspense>
)
}
由於 OpenGl 不能直接使用兩個一模一樣的 模型(mesh)
copy()簡單的說就是複制一個對象的屬性值賦值給給另一個對像對應的屬性。
clone()是相當於新建一個對象,然後復制原對象的屬性值賦值給新的對像對應屬性,也就是說通過克隆方法.clone()創建一個和原來對象完全一樣的對象。
function _GltfScene() {
const gltf = useLoader(GLTFLoader, 'https://modelviewer.dev/shared-assets/models/NeilArmstrong.glb')
const { nodes, materials } = gltf
const { scene } = useThree()
const cloneScene = gltf.scene.clone()
return (
<Suspense fallback={null} scale={1}>
<Clone>
<primitive object={cloneScene} />
</Clone>
</Suspense>
)
}
載入後只使用 {mesh} ,重新添加
function Ruby(props) {
const { nodes } = useGLTF('https://vazxmixjsiawhamofees.supabase.co/storage/v1/object/public/models/ruby/model.gltf')
return (
<mesh geometry={nodes.Ruby.geometry} dispose={null} {...props}>
<meshPhysicalMaterial clearcoat={1} clearcoatRoughness={0} color="red" transmission={1} thickness={2} roughness={0} />
</mesh>
)
}
載入後分別讀取使用 {mesh,material}
function Duck(props) {
const { nodes, materials } = useGLTF('https://vazxmixjsiawhamofees.supabase.co/storage/v1/object/public/models/duck/model.gltf')
return (
<group {...props} dispose={null}>
<mesh geometry={nodes.character_duck.geometry} material={nodes.character_duck.material} rotation={[Math.PI / 2, 0, 0]}>
<mesh geometry={nodes.character_duckArmLeft.geometry} material={nodes.character_duckArmLeft.material} position={[0.2, 0, -0.63]} />
<mesh geometry={nodes.character_duckArmRight.geometry} material={nodes.character_duckArmRight.material} position={[-0.2, 0, -0.63]} />
<group position={[0, 0, -0.7]}>
<mesh geometry={nodes.Cube1338.geometry} material={nodes.Cube1338.material} />
<mesh geometry={nodes.Cube1338_1.geometry} material={materials['Yellow.043']} />
<mesh geometry={nodes.Cube1338_2.geometry} material={materials['Black.027']} />
</group>
</mesh>
</group>
)
}
載入後分別讀取使用 {mesh,material},再 material 添加新的效果
function Suzi(props) {
const { scene, materials } = useGLTF('/blender-threejs-journey-20k-transformed.glb')
// const { scene, materials } = useGLTF('https://market-assets.fra1.cdn.digitaloceanspaces.com/market-assets/models/suzanne-high-poly/model.gltf')
useLayoutEffect(() => {
scene.traverse((obj) => obj.isMesh && (obj.receiveShadow = obj.castShadow = true))
applyProps(materials.boxBase, {
color: 'black',
roughness: 0,
normalMap: new THREE.CanvasTexture(new FlakesTexture(), THREE.UVMapping, THREE.RepeatWrapping, THREE.RepeatWrapping),
'normalMap-repeat': [40, 40],
normalScale: [0.05, 0.05]
})
})
return <primitive object={scene} {...props} />
}
/*
Auto-generated by: https://github.com/pmndrs/gltfjsx
*/
import React, { useRef } from 'react'
import { useGLTF } from '@react-three/drei'
export default function Model(props) {
const { nodes, materials } = useGLTF('/modelCMD.gltf')
return (
<group {...props} dispose={null}>
<ambientLight intensity={0.1} />
<mesh geometry={nodes.Cube.geometry} material={materials['Material.007']} position={[0.02, 0, 0]} scale={[0.45, 1, 1]} />
<group scale={[1.1, 1, 1]}>
<mesh geometry={nodes.立方體.geometry} material={materials['Material.001']} position={[-0.07, 0, 0.47]} scale={[0.1, 1.01, 0.01]} />
<mesh
geometry={nodes.立方體001.geometry}
material={materials['Material.001']}
position={[-0.07, -0.28, 0.6]}
rotation={[Math.PI / 2, 0, 0]}
scale={[0.1, 0.13, 0.02]}
/>
</group>
<group position={[-0.06, 0, -0.01]} scale={[0.8, 1.01, 1.02]}>
<mesh geometry={nodes.Cube001_1.geometry} material={materials['Material.001']} />
<mesh geometry={nodes.Cube001_2.geometry} material={materials['Material.002']} />
<mesh geometry={nodes.Cube001_3.geometry} material={materials['Material.003']} />
<mesh geometry={nodes.Cube001_4.geometry} material={materials['Material.004']} />
<mesh geometry={nodes.Cube001_5.geometry} material={materials['Material.005']} />
</group>
</group>
)
}
useGLTF.preload('/modelCMD.gltf')